<template>
  <a-spin :spinning="confirmLoading">
    <j-form-container disabled>
      <!-- 主表单区域 -->
      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
        <a-row>
          <a-col :span="12">
            <a-form-model-item label="配方通知单号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="noticeNo">
              <a-input v-model="model.noticeNo" placeholder="" :disabled="true"></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="配方编码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="formulaCode">
              <j-dict-select-tag
                type="list"
                v-model="model.formulaCode"
                dictCode="ips_tsl_formula_list,formula_code,formula_code"
                placeholder=" "
              />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="配方年" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="formulaYear">
              <a-input-number v-model="model.formulaYear" placeholder="" style="width: 100%" :disabled="true" />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="配方号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="formulaNumber">
              <a-input v-model="model.formulaNumber" placeholder=" "></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="配方名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="formulaDefine">
              <a-input v-model="model.formulaDefine" placeholder="" :disabled="true"></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="配方类别" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="formulaCategory">
              <j-dict-select-tag
                type="list"
                v-model="model.formulaCategory"
                dictCode="formula_category"
                placeholder=""
                :disabled="true"
              />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="配方类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="formulaType">
              <j-dict-select-tag
                type="list"
                v-model="model.formulaType"
                dictCode="formula_type"
                placeholder=""
                :disabled="true"
              />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="formulaDesc">
              <j-dict-select-tag
                type="list"
                v-model="model.formulaDesc"
                dictCode="formula_desc"
                placeholder=""
                :disabled="true"
              />
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <a-form-model-item label="视比重" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="apparentProportion">
              <a-input v-model="model.apparentProportion" placeholder=" "></a-input>
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </j-form-container>
    <!-- 子表单区域 -->
    <a-tabs v-model="activeKey" @change="handleChangeTabs">
      <a-tab-pane tab="配方通知单" :key="refKeys[0]" :forceRender="true">
        <j-vxe-table-clone
          keep-source
          :ref="refKeys[0]"
          :loading="ipsTslFormulaNoticeDetailTable.loading"
          :columns="ipsTslFormulaNoticeDetailTable.columns"
          :dataSource="ipsTslFormulaNoticeDetailTable.dataSource"
          :maxHeight="300"
          :disabled="formDisabled"
          :rowNumber="true"
          :rowSelection="false"
          :toolbar="false"
          @edit-closed="editClosedEvent"
        />
      </a-tab-pane>
    </a-tabs>
  </a-spin>
</template>

<script>
import { getAction, postAction } from '@/api/manage'
import { JVxeTableModelMixin } from '@/mixins/JVxeTableModelMixin.js'
import { JVXETypes } from '@/components/jeecg/JVxeTable'
import { getRefPromise, VALIDATE_FAILED } from '@/components/jeecg/JVxeTable/utils/vxeUtils.js'
import { validateDuplicateValue } from '@/utils/util'
import JFormContainer from '@/components/jeecg/JFormContainer'
import Decimal from 'decimal.js'

export default {
  name: 'FormulaNoticeForm',
  mixins: [JVxeTableModelMixin],
  components: {
    JFormContainer,
  },
  data() {
    return {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 },
      },
      model: {},
      // 新增时子表默认添加几行空数据
      addDefaultRowNum: 1,
      validatorRules: {},
      refKeys: ['ipsTslFormulaNoticeDetail'],
      tableKeys: ['ipsTslFormulaNoticeDetail'],
      activeKey: 'ipsTslFormulaNoticeDetail',
      // tsl配方通知单明细
      ipsTslFormulaNoticeDetailTable: {
        loading: false,
        dataSource: [],
        columns: [
          {
            title: '工序',
            key: 'processCode',
            type: JVXETypes.normal,
            options: [],
            dictCode: 'process_code',
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: 'material_id',
            key: 'materialId',
            type: 'hidden',
          },
          {
            title: '物料名称',
            key: 'materialName',
            type: JVXETypes.normal,
            popupCode: 'formula_material_detail',
            field: 'id,name,code,none_spec',
            orgFields: 'id,name,code,none_spec',
            destFields: 'materialId,materialName,materialCode,materialSpec',
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: '规格型号',
            key: 'materialSpec',
            type: JVXETypes.normal,
            width: '200px',
            placeholder: '请输入${title}',
            disabled: true,
            defaultValue: '',
          },
          {
            title: '配方（%）',
            key: 'formulaProportion',
            type: JVXETypes.normal,
            width: '200px',
            placeholder: '请输入${title}',
            defaultValue: '',
            statistics: ['sum'],
            validateRules: [
              {
                pattern: /^((100(\.0{1,4})?)|([1-9]?\d)(\.\d{1,4})?|0(\.\d{1,4})?)$/,
                message: '请输入0-100之间的数值（最多4位小数）',
              },
            ],
          },
          {
            title: '1000kg',
            key: 'weight1000Kg',
            type: JVXETypes.normal,
            width: '200px',
            placeholder: '',
            defaultValue: '',
            statistics: ['sum'],
          },
          {
            title: '3500kg',
            key: 'weight3500Kg',
            type: JVXETypes.normal,
            width: '200px',
            placeholder: '',
            defaultValue: '',
            statistics: ['sum'],
          },
          {
            title: '4000kg',
            key: 'weight4000Kg',
            type: JVXETypes.normal,
            width: '200px',
            placeholder: '',
            defaultValue: '',
            statistics: ['sum'],
          },
          {
            title: '5000kg',
            key: 'weight5000Kg',
            type: JVXETypes.normal,
            width: '200px',
            placeholder: '',
            defaultValue: '',
            statistics: ['sum'],
          },

          /*{
              title: 'material_name',
              key: 'material_name',
              type:"hidden"
            },*/

          {
            title: 'materialCode',
            type: JVXETypes.normal,
            key: 'materialCode',
            type: 'hidden',
          },

          /*{
              title: 'material_spec',
              key: 'material_spec',
              type:"hidden"
            },*/
        ],
      },
      url: {
        list: '/ipstslformulanotice/ipsTslFormulaNotice/list',
        add: '/ipstslformulanotice/ipsTslFormulaNotice/add',
        edit: '/ipstslformulanotice/ipsTslFormulaNotice/edit',
        queryById: '/ipstslformulanotice/ipsTslFormulaNotice/queryById',
        generateTslNoticeNo: '/ipstslformulanotice/ipsTslFormulaNotice/generateTslNoticeNo',
        getRelateFormulaResult: '/ipstslformulanotice/ipsTslFormulaNotice/getRelateFormulaResult',
        // 配方查看
        queryFormulaDetail: '/ipstslformulalist/ipsTslFormulaList/queryFormulaDetail',
        ipsTslFormulaNoticeDetail: {
          // 配方通知单
          list: '/ipstslformulanotice/ipsTslFormulaNotice/queryIpsTslFormulaNoticeDetailByFormulaCode',
        },
      },
      // 新增配方清单表格配置
      formulaListTable: {
        columns: [
          { title: '物料编码', dataIndex: 'materialCode', key: 'materialCode', align: 'center', width: '16%' },
          { title: '物料名称', dataIndex: 'materialName', key: 'materialName', align: 'center', width: '20%' },
          { title: '规格型号', dataIndex: 'materialSpec', key: 'materialSpec', align: 'center', width: '15%' },
          { title: '单位', dataIndex: 'materialUnit', key: 'materialUnit', align: 'center', width: '16%' },
          { title: '配方%', dataIndex: 'formulaProportion', key: 'formulaProportion', align: 'center', width: '16%' },
          { title: '实际数量', dataIndex: 'actualNumber', key: 'actualNumber', align: 'center', width: '16%' },
        ],
        dataSource: [],
      },
    }
  },
  watch: {
    // 监听配方编码变化
    'model.formulaCode': {
      immediate: true,
      handler(newVal) {
        if (newVal) {
          this.loadFormulaDetail(newVal)
        } else {
          this.clearFormulaData()
        }
      },
    },
  },
  props: {
    //表单禁用
    disabled: {
      type: Boolean,
      default: false,
      required: false,
    },
  },
  computed: {
    totalFormulaProportion() {
      return this.formulaListTable.dataSource
        .reduce((sum, item) => {
          return sum + (parseFloat(item.formulaProportion) || 0)
        }, 0)
        .toFixed(4)
    },
    totalActualNumber() {
      return this.formulaListTable.dataSource
        .reduce((sum, item) => {
          return sum + (parseFloat(item.actualNumber) || 0)
        }, 0)
        .toFixed(4)
    },
    formDisabled() {
      return this.disabled
    },
  },
  created() {},
  methods: {
    addBefore() {
      this.ipsTslFormulaNoticeDetailTable.dataSource = []
    },
    getAllTable() {
      let values = this.tableKeys.map((key) => getRefPromise(this, key))
      return Promise.all(values)
    },
    editBefore() {
      // 根据配方号，获取主表id
      // if (this.model.id) {
      //   let params = { id: this.model.id }
      //   this.requestSubTableData(this.url.ipsTslFormulaNoticeDetail.list, params, this.ipsTslFormulaNoticeDetailTable)
      // }
    },
    /** 调用完edit()方法之后会自动调用此方法 */
    editAfter() {
      this.$nextTick(() => {})
      // 加载子表数据
      if (this.model.formulaCode) {
        let params = { formulaCode: this.model.formulaCode }
        this.requestSubTableData(this.url.ipsTslFormulaNoticeDetail.list, params, this.ipsTslFormulaNoticeDetailTable)
      }
    },
    //校验所有一对一子表表单
    validateSubForm(allValues) {
      return new Promise((resolve, reject) => {
        Promise.all([])
          .then(async () => {
            // 获取配方通知单子表的物料编码
            let noticeCodes = null
            noticeCodes = this.ipsTslFormulaNoticeDetailTable.dataSource.map((item) => item.materialCode)
            console.log('init noticeCodes getting:' + noticeCodes)
            if (noticeCodes == null || noticeCodes == '') {
              noticeCodes = allValues.tablesValue[0].tableData.map((item) => item.materialCode)
            }

            // 获取配方清单子表的物料编码
            const listCodes = this.formulaListTable.dataSource.map((item) => item.materialCode)

            console.log('noticeCodes:' + noticeCodes)
            console.log('listCodes:' + listCodes)

            const noticeSet = new Set(noticeCodes)
            const listSet = new Set(listCodes)

            const isSame =
              noticeCodes.length === listCodes.length &&
              noticeCodes.every((code) => listSet.has(code)) &&
              listCodes.every((code) => noticeSet.has(code))

            if (!isSame) {
              try {
                const confirm = await this.$confirm({
                  title: '提示',
                  content: '配方通知单和配方清单的物料不一致，是否继续保存？',
                  okText: '确定',
                  cancelText: '取消',
                  onOk: function () {
                    resolve(allValues)
                  },
                })
              } catch (error) {
                reject(error)
              }
            } else {
              resolve(allValues)
            }
            //resolve(allValues)
          })
          .catch((e) => {
            if (e.error === VALIDATE_FAILED) {
              // 如果有未通过表单验证的子表，就自动跳转到它所在的tab
              this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
            } else {
              console.error(e)
            }
          })
      })
    },
    /** 整理成formData */
    classifyIntoFormData(allValues) {
      let main = Object.assign(this.model, allValues.formValue)
      return {
        ...main, // 展开
        ipsTslFormulaNoticeDetailList: allValues.tablesValue[0].tableData,
      }
    },
    validateError(msg) {
      this.$message.error(msg)
    },
    async generateTslNoticeNo() {
      try {
        const res = await getAction(this.url.generateTslNoticeNo, {})
        if (res.success) {
          return res.result
        } else {
          this.$message.warning(res.message)
          return ''
        }
      } catch (e) {
        console.error('生成通知单号失败', e)
        return ''
      }
    },
    // getPfCode() {
    //   postAction('/sys/fillRule/executeRuleByCode/tsl_formula_notice_code', {}).then((res) => {
    //     this.model.noticeNo = res.result
    //   })
    // },
    async add() {
      //this.getPfCode()
      if (typeof this.addBefore === 'function') this.addBefore()
      this.eachAllTable((item) => {
        //update-begin-author:taoyan date:20210315 for: 一对多jvex 默认几行不好使了 LOWCOD-1349
        setTimeout(() => {
          item.addRows()
        }, 30)
        //update-end-author:taoyan date:20210315 for: 一对多jvex 默认几行不好使了 LOWCOD-1349
      })
      if (typeof this.addAfter === 'function') this.addAfter(this.model)
      this.edit(this.model)
      //重设noticeNo
      let defaultCode = await this.generateTslNoticeNo()
      this.model.noticeNo = defaultCode
    },
    // 加载配方详情
    async loadFormulaDetail(formulaCode) {
      try {
        const res = await getAction(this.url.list, { formulaCode: formulaCode })
        if (res.success && res.result?.records?.length > 0) {
          // 安全合并数据到现有 model
          this.model = {
            ...this.model, // 保留现有属性（如 noticeNo）
            ...res.result.records[0], // 添加新属性
          }
        } else {
          // this.$message.warning(res.message || '配方数据加载失败')
          this.clearFormulaData()
        }
      } catch (e) {
        console.error('物料数据加载失败', e)
        this.$message.error('物料数据加载失败')
        this.clearFormulaData()
      }
    },
    // 清空配方数据
    clearFormulaData() {
      // 确保 model 对象存在
      this.model = this.model || {}
      // 清空主表字段
      const clearFields = [
        'formulaYear',
        'formulaNumber',
        'formulaDefine',
        'formulaCategory',
        'formulaType',
        'formulaDesc',
      ]
      clearFields.forEach((field) => {
        this.$set(this.model, field, undefined)
      })
      // 清空配方清单
      this.formulaListTable.dataSource = []
    },
    editClosedEvent({ row, column }) {
      if (['formulaProportion', 'materialName'].includes(column.property)) {
        if (!row.materialId || row.materialId == null || row.materialId == undefined) {
          return
        }
        if (!row.formulaProportion || row.formulaProportion == null || row.formulaProportion == undefined) {
          return
        }
        try {
          getAction(this.url.getRelateFormulaResult, {
            formulaAttribute: '1',
            formulaProportion: row.formulaProportion,
            materialId: row.materialId,
          }).then((res) => {
            if (res.success) {
              this.$set(row, 'weight1000Kg', res.result.weight1000Kg)
              this.$set(row, 'weight3500Kg', res.result.weight3500Kg)
              this.$set(row, 'weight4000Kg', res.result.weight4000Kg)
              this.$set(row, 'weight5000Kg', res.result.weight5000Kg)

              // 手动触发VxeTable的重新计算
              this.$nextTick(() => {
                const jvxeTable = this.$refs[this.refKeys[0]]
                if (jvxeTable) {
                  // 访问内部的 VxeGrid 实例并调用 recalculate
                  const vxeGrid = jvxeTable.$refs.vxe
                  if (vxeGrid) {
                    const xTable = vxeGrid.$refs.xTable
                    if (xTable) {
                      xTable.handleTableData()
                      xTable.updateFooter()
                      xTable.updateCache()
                      xTable.checkSelectionStatus()
                      xTable.recalculate()
                    }
                  }
                }
              })
            } else {
              this.$message.warning(res.message)
              this.$set(row, 'weight1000Kg', '')
              this.$set(row, 'weight3500Kg', '')
              this.$set(row, 'weight4000Kg', '')
              this.$set(row, 'weight5000Kg', '')
            }
          })
        } catch (e) {
          console.error('获取配方公式计算结果失败', e)
          this.$set(row, 'weight1000Kg', '')
          this.$set(row, 'weight3500Kg', '')
          this.$set(row, 'weight4000Kg', '')
          this.$set(row, 'weight5000Kg', '')
        }
      }
    },
    formulaListFooter() {
      return (
        <div style="width: 100%; display: flex; gap: 8px; flex-wrap: nowrap; overflow-x: auto;">
          <div style="order: 1; flex: 0 1 auto; min-width: 15%; text-align: center; border-right: 1px solid #f0f0f0;">
            合计
          </div>
          <div style="order: 2; flex: 0 1 auto; min-width: 62.7%; text-align: right; border-right: 1px solid #f0f0f0;">
            {this.totalFormulaProportion}
          </div>
          <div style="order: 3; flex: 0 1 auto; min-width: 15.2%; text-align: right;">{this.totalActualNumber}</div>
        </div>
      )
    },
  },
}
</script>

<style scoped></style>
